local L = LibStub("AceLocale-3.0"):GetLocale("DoTimer_Options")
local SECTION_NAME = "DoTimer Timers";
local sharedMedia = LibStub and LibStub:GetLibrary("LibSharedMedia-3.0", 1);

local function createGUI(name)
    local optionsTable = {
        { -- section 1
            { -- column 1
                {
                    type = "text",
                    text = name,
                },
            },
        },
        { -- section 2
            { -- column 1
                {
                    type = "text",
                    small = true,
                    text = L["General"],
                },
                {
                    title = L["Timer Format"],
                    type = "dropDownSelector",
                    tooltipText = L["Sets the format of the timer.  The format dictates the major appearance, and several timer settings only apply to one of the formats."],
                    values = {"bar", "icon"};
                    setting = "timerFormat",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Clickable"],
                    type = "checkButton",
                    tooltipText = L["If checked, the timer will respond to mouse events such as clicking and mousing over."],
                    setting = "clickable",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Tenths"],
                    type = "checkButton",
                    tooltipText = L["If checked, the time remaining will display tenths of a second when the time remaining is less than 10 seconds."],
                    setting = "tenths",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Sound Alert"],
                    type = "checkButton",
                    tooltipText = L["If checked, a sound will be played when the timer hits its red point."],
                    setting = "soundAlert",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Ghosts"],
                    type = "checkButton",
                    tooltipText = L["If checked, the timer will turn into a ghost timer when finished."],
                    setting = "ghosts",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Tooltips"],
                    type = "checkButton",
                    tooltipText = L["If checked, the timer will display a tooltip when moused over."],
                    setting = "tooltips",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Time Format"],
                    type = "dropDownSelector",
                    tooltipText = L["If letters, then the timer's time remaining will be displayed in a format like '5s'.  If digital, it will be ':05'."],
                    values = {"letters", "digital"};
                    setting = "timeFormat",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Alpha"],
                    type = "slider",
                    tooltipText = L["Sets the alpha of the timer.  Certain parts of the timer, such as text, are not affected by this setting."],
                    minValue = 0, 
                    maxValue = 1,
                    valueStep = .05,
                    setting = "alpha",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Scale"],
                    type = "slider",
                    tooltipText = L["Sets the scale of the timer."],
                    minValue = .5, 
                    maxValue = 2,
                    valueStep = .1,
                    setting = "scale",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Ghost Duration"],
                    type = "slider",
                    tooltipText = L["Sets the duration that the timer persists after finishing as a ghost.  Zero means that the timer will stay as a ghost until all timers in its group are also ghosts."],
                    minValue = 0, 
                    maxValue = 15,
                    valueStep = 1,
                    setting = "ghostLength",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Fade In Length"],
                    type = "slider",
                    tooltipText = L["Sets the amount of time it takes the timer to fade in when it begins."],
                    minValue = 0, 
                    maxValue = 5,
                    valueStep = .5,
                    setting = "fadeInLength",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Fade Out Length"],
                    type = "slider",
                    tooltipText = L["Sets the amount of time it takes the timer to fade out when it finishes."],
                    minValue = 0, 
                    maxValue = 5,
                    valueStep = .5,
                    setting = "fadeOutLength",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
            },
            { -- column 2
                {
                    type = "text",
                    small = true,
                    text = L["Icon Format"],
                },
                {
                    title = L["Show Cooldown"],
                    type = "checkButton",
                    tooltipText = L["If checked, a cooldown clock will display on the anchor."],
                    setting = "iconShowCooldown",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Reverse Cooldown"],
                    type = "checkButton",
                    tooltipText = L["If checked, the cooldown clock will increase darkness instead of increasing lightness."],
                    setting = "iconReverseCooldown",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Flip Text"],
                    type = "checkButton",
                    tooltipText = L["If checked, the time remaining string, if displayed outside the icon, will flip to the oppsosite side of the icon."],
                    setting = "iconFlipText",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = "Use Background",
                    type = "checkButton",
                    tooltipText = "If checked, the border around the icon will use the background color, selected below, instead of the color of the duration text.",
                    setting = "iconUseBG",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Display Format"],
                    type = "dropDownSelector",
                    tooltipText = L["Sets where the time remaining will appear: outside the icon, inside the icon, or nowhere."],
                    values = {"inside", "outside", "none"};
                    setting = "iconDisplayFormat",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Font Height"],
                    type = "slider",
                    tooltipText = L["Sets the height of the font outside the icon."],
                    --tooltipText = "Sets the height of the font showing the duration text.",
                    minValue = 5, 
                    maxValue = 20,
                    valueStep = 1,
                    setting = "iconFontHeight",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                "BREAK",
                {
                    title = L["Preview"],
                    type = "button",
                    tooltipText = L["Show a preview of timers with this setting."],
                    func = function()
                        local offset = 0;
                        for i = 1, 2 do
                            local g = "Scary Mob " .. i;
                            for j = 1, 3 do
                                TimerLib:NewTimer({duration = 20, time = GetTime() - offset, name = "Cool Timer " .. j}, g, nil, name);
                                offset = offset + .5;
                            end
                        end
                    end,
                },
                "BREAK",
                {
                    type = "text",
                    small = true,
                    text = L["Colors"],
                },
                {
                    title = L["Start"],
                    type = "colorSelect",
                    tooltipText = L["Sets the initial color of the timer."],
                    setting = "startColor",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Middle"],
                    type = "colorSelect",
                    tooltipText = L["Sets the color the timer will change to at 50% completion."],
                    setting = "middleColor",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Final"],
                    type = "colorSelect",
                    tooltipText = L["Sets the color the timer will change to at 'Red Point' seconds left."],
                    setting = "finalColor",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Ghost"],
                    type = "colorSelect",
                    tooltipText = L["Sets the color of the ghost timer."],
                    setting = "ghostColor",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Bar Text"],
                    type = "colorSelect",
                    tooltipText = L["Sets the color of the bar text."],
                    setting = "barTextColor",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Bar BG"],
                    type = "colorSelect",
                    tooltipText = L["Sets the color of the bar background."],
                    setting = "barBackgroundColor",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
            },
            { -- column 3
                {
                    type = "text",
                    small = true,
                    text = L["Bar Format"],
                },
                {
                    title = L["Flip Icon"],
                    type = "checkButton",
                    tooltipText = L["If checked, the icon will be displayed to the right of the bar instead of the left."],
                    setting = "barFlipIcon",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Show Icon"],
                    type = "checkButton",
                    tooltipText = L["If unchecked, no icon will be shown next to the bar."],
                    setting = "barShowIcon",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Reversed"],
                    type = "checkButton",
                    tooltipText = L["If checked, the bar will shrink/grow from the right/top instead of the left/bottom."],
                    setting = "barReversed",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Grow"],
                    type = "checkButton",
                    tooltipText = L["If checked, the bar will grow instead of shrink."],
                    setting = "barGrow",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Orientation"],
                    type = "dropDownSelector",
                    tooltipText = L["Sets the orientation of the bar."],
                    values = {"horizontal", "vertical"},
                    setting = "barOrientation",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Texture"],
                    type = "dropDown",
                    tooltipText = L["Sets the texture for the bar."],
                    func = function()
                        local level = UIDROPDOWNMENU_MENU_LEVEL;
                        local info;
                        if (level == 1) then
                            info = UIDropDownMenu_CreateInfo();
                            info.notCheckable = true;
                            info.hasArrow = true;
                            info.text = "Horizontal";
                            info.value = "horiz";
                            UIDropDownMenu_AddButton(info);
                            
                            info = UIDropDownMenu_CreateInfo();
                            info.notCheckable = true;
                            info.hasArrow = true;
                            info.text = "Vertical";
                            info.value = "vert";
                            UIDropDownMenu_AddButton(info);
                            
                            if sharedMedia then
                                for i = 1, math.ceil(#sharedMedia:List("statusbar") / 10) do
                                    info = UIDropDownMenu_CreateInfo();
                                    info.notCheckable = true;
                                    info.hasArrow = true;
                                    info.text = "Shared Media-" .. i;
                                    info.value = "shared" .. i;
                                    UIDropDownMenu_AddButton(info, level);
                                end
                            end
                        elseif (level == 2) then
                            local list = UIDROPDOWNMENU_MENU_VALUE;
                            local values, start, finish;
                            if list == "horiz" then
                                values = {"Aluminium", "Banto", "Charcoal", "Elven", "Glaze", "Gloss", "Grunge", "Halycon", "Healbot", "LiteStep", "Moonmaster", "OtraviCB", "Perl", "Rocks", "Runes", "Smooth", "Solid", "Steel", "Stone"};
                                start = 1;
                                finish = #values;
                            elseif list == "vert" then
                                values = {"Aluminium-V", "Banto-V", "Charcoal-V", "Elven-V", "Glaze-V", "Gloss-V", "Grunge-V", "Halycon-V", "Healbot-V", "LiteStep-V", "Moonmaster-V", "OtraviCB-V", "Perl-V", "Rocks-V", "Runes-V", "Smooth-V", "Solid-V", "Steel-V", "Stone-V"};
                                start = 1;
                                finish = #values;
                            elseif string.find(list, "shared") then
                                values = sharedMedia and sharedMedia:List("statusbar");
                                local group = string.match(list, "(%d+)");
                                start = (10 * (group - 1)) + 1;
                                finish = 10 * group;
                            end
                            if values then
                                for i = start, finish do
                                    local value = values[i];
                                    if value then
                                        info = UIDropDownMenu_CreateInfo();
                                        info.text = value;
                                        info.checked = TimerLib:Get("timerSettings", name, "barTexture") == value;
                                        info.func = function() 
                                            TimerLib:Set("timerSettings", name, "barTexture", value);
                                            CloseDropDownMenus(); 
                                            InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name == "Default Timer" and "main" or name);
                                        end
                                        UIDropDownMenu_AddButton(info, level);
                                    end
                                end
                            end
                        end
                    end,
                    setting = "barTexture",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Scaling"],
                    type = "dropDownSelector",
                    tooltipText = L["Sets how the bar will change its value.  If standard, it will change linearly.  If absolute, it will not change until it hits the Absolute Scale setting.  If exponential, the bar will change faster when the timer is nearing completion."],
                    values = {"standard", "absolute", "exponential"},
                    setting = "barScaling",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Major Length"],
                    type = "slider",
                    tooltipText = L["Sets the major length of the bar.  This is its width when horizontal and height when vertical."],
                    minValue = 50, 
                    maxValue = 250,
                    valueStep = 10,
                    setting = "barMajorLength",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Minor Length"],
                    type = "slider",
                    tooltipText = L["Sets the minor length of the bar.  This is its height when horizontal and width when vertical."],
                    minValue = 5, 
                    maxValue = 30,
                    valueStep = 1,
                    setting = "barMinorLength",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Font Height"],
                    type = "slider",
                    tooltipText = L["Sets the height of the font inside the bar."],
                    minValue = 5, 
                    maxValue = 20,
                    valueStep = 1,
                    setting = "barFontHeight",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Absolute Scale"],
                    type = "slider",
                    tooltipText = L["Sets the absolute scale of the bar.  If the scaling is set to 'absolute', the bar won't change until the timer has this much time remaining, at which point the bar will change as if the timer's duration is this setting."],
                    minValue = 1, 
                    maxValue = 30,
                    valueStep = 1,
                    setting = "barAbsScale",
                    hasToggle = name ~= "Default Timer",
                    notSimple = true,
                },
                {
                    title = L["Text Format"],
                    type = "editBoxString",
                    tooltipText = L["Enter here the format for the text inside the bar.\n\nValid formatting codes:\n\n    %s: Name of the timer\n    %d: Time remaining\n    %t: Timer's group name\n\nNormally, the text is anchored to the left.  However, if you want to display some or all of the text anchored to the right, this is how you do it:\n\nAdd '&' with a ':' on EITHER (NOT BOTH) side of it.  \nThe ':' governs which side is given preference if the \nbar length is too short to display the entire message.\n\nExample (Default Value): '%s&:%d', on a short bar: |Cool Ti... 0:15|"],
                    setting = "barTextFormat",
                    hasToggle = name ~= "Default Timer",
                },
                {
                    title = L["Red Point"],
                    type = "editBoxString",
                    tooltipText = "Type in here the point at which you want the timer to turn its final color (default red).  Type it in the form '5m', '10s', '5m 30s', etc. (no quotes).",
                    setting = "redPoint",
                    hasToggle = name ~= "Default Timer",
                    setting = "redPoint",
                    notSimple = true,
                    scripts = {
                        OnEditFocusGained = function(self) 
                            local num;
                            if self.Get then
                                num = self.Get(self.setting);
                            else
                                num = self.module:Get(self.setting);
                            end
                            self:SetText(text and TimerLib.numToText(num) or ""); 
                            self:HighlightText(); 
                        end,
                        OnEnterPressed = function(self) 
                            local text = self:GetText();
                            local num = TimerLib.textToNum(text);
                            if self.Set then
                                self.Set(this.setting, num);
                            else
                                self.module:Set(this.setting, num); 
                            end
                            if self.toggle then self.toggle:SetChecked(true); end
                            self:ClearFocus();
                        end,
                    },
                },
                "BREAK",
            },
        },
    };
    
    if name == "Default Timer" then
        if not AsheylaLib:InSimpleMode() then
            local newButton = {
                title = L["Make New Setting!"],
                type = "editBoxString",
                tooltipText = L["Type in the name of a new timer setting to be customized."],
                scripts = {
                    OnEditFocusGained = function(self) self:SetText(""); self:HighlightText() end,
                    OnEnterPressed = function(self) 
            			local text = self:GetText();
            			if not TimerLib:Get("timerSettings", text) then
                            TimerLib:Set("timerSettings", text, {});
                            createGUI(text);
                        end
                        GUILib:ShowPanel(SECTION_NAME, text == "Default Anchor" and "main" or text);
                        self:ClearFocus();
            		end,
                },
            };
            optionsTable[1][1][1] = {optionsTable[1][1][1], newButton};
        end
    elseif name ~= "DoTimer Timer" and name ~= "Cooldowns Timer" and name ~= "PlayerAuras Timer" then
        local newButton1 = {
            title = L["Delete"],
            type = "button",
            tooltipText = L["Deletes this setting."],
            func = function() 
                local frame = StaticPopup_Show("TIMERLIBTIMER", name)
                frame.data = name;
            end,
        };
        local newButton2 = {
            title = L["Basis Timer Setting"],
            type = "dropDown",
            tooltipText = L["Select the timer setting you want to have applied for the settings you don't set up below (i.e., ones that don't have their little checkbox checked)."],
            func = function()
                local setting = "reference";
                local info;
                for setName, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                    if setName ~= "Default Timer" and setName ~= name then
                        info = UIDropDownMenu_CreateInfo();
                        info.text = setName;
                        info.checked = setName == TimerLib:Get("timerSettings", name, setting);
                        info.func = function() 
                            TimerLib:Set("timerSettings", name, setting, setName);
                            CloseDropDownMenus(); 
                            InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name);
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                end
                
                info = UIDropDownMenu_CreateInfo();
                info.text = L["None"];
                info.tooltipTitle = L["Description"];
                info.tooltipText = L["If you select 'None', a default value will be found instead."];
                info.checked = TimerLib:Get("timerSettings", name, setting) == nil;
                info.func = function() 
                    TimerLib:Set("timerSettings", name, setting, nil);
                    CloseDropDownMenus(); 
                    InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name);
                end
                UIDropDownMenu_AddButton(info);
            end,
            setting = "reference",
        };
        optionsTable[1][1][1] = {optionsTable[1][1][1], newButton1, newButton2};
    else
        local newButton = {
            title = L["Basis Timer Setting"],
            type = "dropDown",
            tooltipText = L["Select the timer setting you want to have applied for the settings you don't set up below (i.e., ones that don't have their little checkbox checked)."],
            func = function()
                local setting = "reference";
                local info;
                for setName, settings in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
                    if setName ~= "Default Timer" and setName ~= name then
                        info = UIDropDownMenu_CreateInfo();
                        info.text = setName;
                        info.checked = setName == TimerLib:Get("timerSettings", name, setting);
                        info.func = function() 
                            TimerLib:Set("timerSettings", name, setting, setName);
                            CloseDropDownMenus(); 
                            InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name);
                        end
                        UIDropDownMenu_AddButton(info);
                    end
                end
                
                info = UIDropDownMenu_CreateInfo();
                info.text = L["None"];
                info.tooltipTitle = L["Description"];
                info.tooltipText = L["If you select 'None', a default value will be found instead."];
                info.checked = TimerLib:Get("timerSettings", name, setting) == nil;
                info.func = function() 
                    TimerLib:Set("timerSettings", name, setting, nil);
                    CloseDropDownMenus(); 
                    InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name);
                end
                UIDropDownMenu_AddButton(info);
            end,
            setting = "reference",
        };
        optionsTable[1][1][1] = {optionsTable[1][1][1], newButton};
    end
    
    local defaultFunc = function()
        TimerLib:Set("timerSettings", name, {});
        InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, name == "Default Timer" and "main" or name);
    end
    
    local getFunc = function(...)
        local val, isReal;
        local checked = TimerLib:AcquireTable();
        local ref = name;
        while ref and val == nil and not checked[ref] do
            val = TimerLib:Get("timerSettings", ref, ...);
            isReal = val ~= nil and ref == name;
            checked[ref] = true;
            ref = TimerLib:Get("timerSettings", ref, "reference");
        end
        TimerLib:ReleaseTable(checked);
        if val == nil then
            val = TimerLib:Get("timerSettings", "Default Timer", ...);
        end
        return val, isReal;
    end
    
    local setFunc = function(...)
        TimerLib:Set("timerSettings", name, ...);
    end
    
    local toggleTooltip = L["If this checkbutton is unchecked, the setting does not apply and a default value will be used instead.  The default value will be found first by looking at the value in the anchor's default timer setting, then at the value in Default Timer."];

    GUILib:SetGUIPanel(SECTION_NAME, name == "Default Timer" and "main" or name, TimerLib, optionsTable, {default = defaultFunc, get = getFunc, set = setFunc, toggleTooltip = toggleTooltip, allSimple = true});
end

StaticPopupDialogs["TIMERLIBTIMER"] = {
    text = L["You are about to delete the timer setting |cff00ff00%s|r.  Do you wish to proceed?"],
    button1 = L["Delete"],
    button2 = L["Cancel"],
    OnAccept = function(self, name) 
        TimerLib:Set("timerSettings", name, nil);
        local cats = INTERFACEOPTIONS_ADDONCATEGORIES;
        for i = 1, #cats do
            if cats[i].name == name then
                table.remove(cats, i);
                break;
            end
        end
        for i = 1, #cats do
            if cats[i].name == SECTION_NAME then
                if not (cats[i + 1] and cats[i + 1].parent == cats[i].name) then
                    cats[i].hasChildren = false;
                    cats[i].collapsed = nil;
                end
                break;
            end
        end
        InterfaceOptionsFrame:Hide(); GUILib:ShowPanel(SECTION_NAME, "main");
    end,
    whileDead = 1,
    hideOnEscape = 1,
    timeout = 0,
}

local blacklist = {
    ["Default Timer"] = true,
    ["DoTimer Timer"] = true,
    ["Cooldowns Timer"] = true,
    ["PlayerAuras Timer"] = true,
};

local function createTimerGUI()
    if AsheylaLib:InSimpleMode() then
        createGUI("Default Timer");
    else
        createGUI("Default Timer");
        createGUI("DoTimer Timer");
        createGUI("Cooldowns Timer");
        createGUI("PlayerAuras Timer");
        for name in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
            if not blacklist[name] then
                createGUI(name);
            end
        end
    end
end
createTimerGUI();
GUILib:AddGUICreationScript(createTimerGUI);

local existing = {};
GUILib:AddProfileChangeScript(function()
    table.wipe(existing);
    local cats = INTERFACEOPTIONS_ADDONCATEGORIES;
    local parent;
    for i = #cats, 1, -1 do
        if cats[i].parent == SECTION_NAME then
            if TimerLib:Get("timerSettings", cats[i].name) then
                table.insert(existing, cats[i].name);
                existing[cats[i].name] = true;
            else
                table.remove(cats, i);
            end
        elseif cats[i].name == SECTION_NAME then
            parent = cats[i];
        end
    end
    if #existing == 0 then
        parent.hasChildren = false;
        parent.collapsed = nil;
    end
    
    for name in AsheylaLib:Alphabetize(TimerLib:Get("timerSettings")) do
        if name ~= "Default Timer" and not existing[name] then
            createGUI(name);
        end
    end
end);
